<?php
namespace App\Service\Alipay;

class AlipayRsaService
{

    /**
     * RSA签名
     * @param array $params 请求参数
     * @return bool|string
     */
    public static function rsaSign($params)
    {

        //待签名字符串
        $sign_str = self::getSignContent($params);

        //私钥文件地址
        $private_key_file = sprintf('%s/alipay/%s/rsa_private_key_pkcs8.pem', storage_path('cert'), $params['app_id']);
        if (!is_file($private_key_file)) {
            return false;
        }

        //获取私钥文件内容
        $pri_key = file_get_contents($private_key_file);

        //转换为openssl格式密钥
        $res = openssl_get_privatekey($pri_key);
        if (!$res) {
            return false;
        }

        //生成签名
        if ('RSA2' == $params['sign_type']) {
            openssl_sign($sign_str, $sign, $res, OPENSSL_ALGO_SHA256);
        } else {
            openssl_sign($sign_str, $sign, $res);
        }

        openssl_free_key($res);

        return base64_encode($sign);

    }


    /**
     * RSA验签
     * @param array $params
     * @return bool
     */
    private function rsaVerify($params)
    {

        $sign = base64_decode($params['sign']);

        //待签名字符串
        $sign_str = $this->getSignContent($params);

        //公钥文件地址
        $public_key_file = sprintf('%s/alipay/%s/rsa_alipay_public_key.pem', storage_path('cert'), $params['app_id']);
        if (!is_file($public_key_file)) {
            return false;
        }

        //获取公钥文件内容
        $public_key = file_get_contents($public_key_file);

        //转换为openssl格式密钥
        $res = openssl_get_publickey($public_key);
        if (!$res) {
            return false;
        }

        if ('RSA2' == $params['sign_type']) {
            $result = (bool)openssl_verify($sign_str, $sign, $res, OPENSSL_ALGO_SHA256);
        } else {
            $result = (bool)openssl_verify($sign_str, $sign, $res);
        }

        openssl_free_key($res);

        return $result;

    }

    /**
     * 生成签名字符串
     * @param array $params 签名参数
     * @return string
     */
    private static function getSignContent($params)
    {

        ksort($params);

        $sign_str = '';
        foreach($params as $k => &$v) {
            if (empty($v) || in_array($k, ['sign', '_url']) || "@" == substr($v, 0, 1)) {
                continue;
            }
            if ($sign_str == '') {
                $sign_str .= $k . '=' . $v;
            } else {
                $sign_str .= '&' . $k . '=' . $v;
            }
        }

        return $sign_str;

    }


    

}